require("Models/Cell")

local Class_Map = class()
Map = Class_Map.new()

function Class_Map:Init()
    self.ObjectParent = GameObject.Find("Map")
    if self.ObjectParent == nil then
        self.ObjectParent = GameObject.New("Map")
        self.ObjectParent.transform.position = Vector3.New(0, 0, 0)
    else
        print("找到组件", self.ObjectParent.name)
    end
    GameObject.DontDestroyOnLoad(self.ObjectParent)

    self.BordersParent = Utils.FindChild(self.ObjectParent, "Borders")

    self.ItemList = {}
end

function Class_Map:CreateMap(MsgMap)
    self.Width = MsgMap.width
    self.Height = MsgMap.height
    self.Map = self:ParseMapData(self.Width, self.Height)
end

function Class_Map:ParseMapData(width, height)
    local mapData = {}
    for i = 0, width - 1 do
        for j = 0, height - 1 do
            local cell = CellClass.new(i, j)
            if j == 0 or j == height - 1 or i == 0 or i == width - 1 then
                cell.CellType = CellType.Border
            end
            if mapData[cell.x] == nil then
                mapData[cell.x] = {}
            end
            mapData[cell.x][cell.y] = cell
        end
    end
    return mapData
end

function Class_Map:GetCell(Cell)
    return self.Map[Cell.x][Cell.y]
end

function Class_Map:GetCells(Cells)
    local cells = {}
    for key, value in ipairs(Cells) do
        local cell = self:GetCell(value)
        if cell then
            if cells[cell.x] == nil then
                cells[cell.x] = {}
            end
            cells[cell.x][cell.y] = cell
        else
            print("获取单位出错，位置", value.x, value.y)
        end
    end
    return cells
end

function Class_Map:SetManors(Manors)
    local cells = {}
    for key, value in ipairs(Manors) do
        local cell = self:GetCell(value)
        if cell then
            self:RecycleUnit(cell)

            cell.owner = value.owner
            cell.CellType = CellType.Manor

            self:UpdateUnit(cell)

            if cells[cell.x] == nil then
                cells[cell.x] = {}
            end
            cells[cell.x][cell.y] = cell
        else
            print("设置领地出错", value.x, value.y)
        end
    end
    return cells
end

function Class_Map:SetTracks(Tracks)
    local cells = {}
    for key, value in ipairs(Tracks) do
        local cell = self:GetCell(value)
        if cell then
            self:RecycleUnit(cell)

            cell.tracker = value.tracker
            cell.CellType = CellType.Track

            self:UpdateUnit(cell)

            if cells[cell.x] == nil then
                cells[cell.x] = {}
            end
            cells[cell.x][cell.y] = cell
        else
            print("设置领地出错", value.x, value.y)
        end
    end
    return cells
end

function Class_Map:JenerateMap()
    local map = self.Map
    if map == nil then
        print("地图加载出错")
        return false
    end
    for key1, value1 in pairs(self.ItemList) do
        for key2, value2 in pairs(value1) do
            GameObject.Destroy(value2)
        end
    end
    self.ItemList = {}

    for key1, value1 in pairs(map) do
        for key2, value2 in pairs(value1) do
            local itemGo = self:CreateUnit(value2)
            if itemGo then
                if self.ItemList[value2.x] == nil then
                    self.ItemList[value2.x] = {}
                end
                self.ItemList[value2.x][value2.y] = itemGo
            end
        end
    end
end

function Class_Map:UpdateUnit(Cell)
    local item = self:CreateUnit(Cell)
    self.ItemList[Cell.x][Cell.y] = item
    if LuaUtils:IsNil(item) then
        print("更新领地地图元素错误", Cell.x, Cell.y)
    end
end

function Class_Map:RecycleUnit(Cell)
    local player
    if Cell.CellType == CellType.Manor then
        player = EntityManager:GetEntity(Cell.owner)
    elseif Cell.CellType == CellType.Track then
        player = EntityManager:GetEntity(Cell.tracker)
    end
    if player then
        local cellTypeID = player.CellTypeID
        local item = self:GetUnit(Cell)
        if item then
            ObjectPool:PushToPool(cellTypeID, item)
        end
    end
end

function Class_Map:CreateUnit(Cell)
    local itemGo
    if Cell.CellType ~= CellType.None then
        local x, y = Cell.x, Cell.y
        local param = {}
        local player
        if Cell.CellType == CellType.Border then
            param.ModelID = 101
            param.Parent = self.BordersParent
        elseif Cell.CellType == CellType.Manor then
            player = EntityManager:GetEntity(Cell.owner)
        elseif Cell.CellType == CellType.Track then
            player = EntityManager:GetEntity(Cell.tracker)
        end
            
        if player ~= nil then
            param.ModelID = player.CellTypeID
            param.Parent = player.Parent
        end

        if param.ModelID then
            param.Name = param.ModelID.."-"..x.."_"..y
            param.Position = Vector3.New(x, 0, y)
            param.Rotation = Quaternion.Euler(0, 0, 0)
            itemGo = EntityFactory:CreateEntity(param)
        end
    end
    return itemGo
end

function Class_Map:GetUnit(Cell)
    local item
    if not LuaUtils:IsNil(self.ItemList[Cell.x][Cell.y]) then
        item = self.ItemList[Cell.x][Cell.y]
    end
    return item
end

function Class_Map:UpdateCells(Msg)
    for key, value in ipairs(Msg.cells) do
        local cell = self:GetCell(value)
        self:RecycleUnit(cell)

        cell = self:UpdateCell(value)
        self:UpdateUnit(cell)
    end

end

function Class_Map:UpdateCell(MsgCell)
    local cell = self:GetCell(MsgCell)
    cell.owner = MsgCell.owner
    cell.tracker = MsgCell.tracker
    cell.CellType = LuaUtils:GetCellType(MsgCell.celltype)
    return cell
end
